<template>
    <div class="main-container">
        <div class="main-header">
            <div class="main-header-function">
                <div>
<!--                    <label>Agent </label>-->
                    <label style="color: rgba(217,6,241,0.81)">{{ agentName }}</label>
<!--                    <label> 编排</label>-->
                </div>
            </div>
            <div class="update-prompt">
                <el-carousel height="30px" direction="vertical" indicator-position="none">
                    <el-carousel-item v-for="item in eventMessages">
                        <el-tag
                                type="danger">
                            <i class="el-icon-info"/>
                            {{ item }}
                        </el-tag>
                    </el-carousel-item>
                </el-carousel>
            </div>
            <div class="main-header-extra">
                <el-select v-model="model" placeholder="请选择模型">
                    <el-option
                            v-for="item in extra.models"
                            :key="item.id"
                            :label="item.name"
                            :value="item.id">
                    </el-option>
                </el-select>
                <el-button type="success" @click="drawer.modelConfig.visible = true">模型参数</el-button>
                <el-button type="primary" icon="el-icon-edit" @click="publishUpdate">发布更新</el-button>
            </div>
        </div>

        <div class="main-body main-layout">
            <div class="main-container">
                <div class="agent-config">
                    <div class="card" style="height: 400px">
                        <div class="card-header">提示词</div>
                        <el-input class="card-body" v-model="prompt" type="textarea" placeholder="填写提示词"/>
                        <div class="card-footer">字数: {{prompt.length}}</div>
                    </div>
                    <div class="card" style="height: 300px">
                        <div class="card-header">
                            <span>选择工具</span>
                            <el-button size="mini" type="primary" @click="selectWebHookToolsEvent">WebHook</el-button>
                        </div>
                        <div class="card-body">
                            <el-row>
                                <el-col :span="12" v-for="item of tools.webhook">
                                    <div class="tool-card">
                                        <div class="tool">
                                            <el-tag size="medium" type="warning">WebHook</el-tag>
                                            <div class="tool-name">{{ item.toolName }}</div>
                                            <div class="tool-operate">
                                                <el-tooltip effect="dark" :content="item.description" placement="top">
                                                    <div>
                                                        <i class="el-icon-question"
                                                           style="color: rgba(64,158,255,0.8)"></i>
                                                    </div>
                                                </el-tooltip>
                                                <i class="el-icon-delete" @click="deleteWebHookEvent(item)" style="color: rgba(245,108,108,0.8)"></i>
                                            </div>
                                        </div>
                                    </div>
                                </el-col>
                            </el-row>
                        </div>
                    </div>
                </div>
            </div>
            <div class="main-container" v-if="agentName">
                <open-ai-chat
                        title="调试和预览"
                        :agent-name="agentName"
                        :username="username"
                        :chatURL="agentChatURL"/>
            </div>
        </div>

        <el-dialog
                :title="dialog.tools.title"
                :close-on-click-modal="false"
                :visible.sync="dialog.tools.visible">
            <el-transfer
                    v-if="dialog.tools.type == 'webhook'"
                    v-model="operate.tools.webhook"
                    :titles="['待选项', '已选项']"
                    filterable
                    :render-content="transferToolRenderContent"
                    :data="extra.tools.webhook"
            ></el-transfer>
        </el-dialog>

        <el-drawer
                title="模型参数配置"
                :visible.sync="drawer.modelConfig.visible"
                direction="rtl">
            <div class="drawer__content">
                <el-form
                        label-width="80px"
                        label-position="left">
                    <el-form-item label="温度: ">
                        <el-switch
                                v-model="extra.modelConfig.temperature.enable">
                        </el-switch>
                        <el-slider
                                v-model="extra.modelConfig.temperature.value"
                                :min="0"
                                :max="2"
                                :step="0.1"
                                input-size="mini"
                                :disabled="!extra.modelConfig.temperature.enable"
                                show-input>
                        </el-slider>
                    </el-form-item>
                    <el-form-item label="top_p: ">
                        <el-switch
                                v-model="extra.modelConfig.topP.enable">
                        </el-switch>
                        <el-slider
                                v-model="extra.modelConfig.topP.value"
                                :min="0"
                                :max="1"
                                :step="0.1"
                                input-size="mini"
                                :disabled="!extra.modelConfig.topP.enable"
                                show-input>
                        </el-slider>
                    </el-form-item>
                    <el-form-item label="存在惩罚: ">
                        <el-switch
                                v-model="extra.modelConfig.presencePenalty.enable">
                        </el-switch>
                        <el-slider
                                v-model="extra.modelConfig.presencePenalty.value"
                                :min="-2"
                                :max="2"
                                :step="0.1"
                                input-size="mini"
                                :disabled="!extra.modelConfig.presencePenalty.enable"
                                show-input>
                        </el-slider>
                    </el-form-item>
                    <el-form-item label="频率惩罚: ">
                        <el-switch
                                v-model="extra.modelConfig.frequencyPenalty.enable">
                        </el-switch>
                        <el-slider
                                v-model="extra.modelConfig.frequencyPenalty.value"
                                :min="-2"
                                :max="2"
                                :step="0.1"
                                input-size="mini"
                                :disabled="!extra.modelConfig.frequencyPenalty.enable"
                                show-input>
                        </el-slider>
                    </el-form-item>
                    <el-form-item label="maxTokens: ">
                        <el-switch
                                v-model="extra.modelConfig.maxTokens.enable">
                        </el-switch>
                        <el-slider
                                v-model="extra.modelConfig.maxTokens.value"
                                :min="1024"
                                :max="4096"
                                :step="1"
                                input-size="mini"
                                :disabled="!extra.modelConfig.maxTokens.enable"
                                show-input>
                        </el-slider>
                    </el-form-item>
                    <el-form-item label="深度思考: ">
                        <el-switch
                                v-model="extra.modelConfig.enableThinking.enable">
                        </el-switch>
                        <div style="margin-left: 20px; color: #409EFF">是否启用深度思考：</div>
                        <el-switch
                                :disabled="!extra.modelConfig.enableThinking.enable"
                                v-model="extra.modelConfig.enableThinking.value">
                        </el-switch>
                    </el-form-item>
                    <el-form-item label="思考长度: ">
                        <el-switch
                                :disabled="!extra.modelConfig.enableThinking.value"
                                v-model="extra.modelConfig.thinkingBudget.enable">
                        </el-switch>
                        <el-slider
                                v-model="extra.modelConfig.thinkingBudget.value"
                                :min="1024"
                                :max="4096"
                                :step="1"
                                input-size="mini"
                                :disabled="!extra.modelConfig.thinkingBudget.enable || !extra.modelConfig.enableThinking.enable"
                                show-input>
                        </el-slider>
                    </el-form-item>
                </el-form>
            </div>
        </el-drawer>

    </div>
</template>

<script>
    import tools from "@/util/Tools";
    import openAiChat from "@/components/chat/OpenAiChat"
    import setter from "@/setting/setter"

    export default {
        name: "agentArrange",
        components: {
            openAiChat
        },
        data() {
            return {
                /* agentId */
                agentId: "",
                /* agentName */
                agentName: "",
                /* 模型 */
                model: "",
                /* 提示词 */
                prompt: "",
                /* 工具 */
                tools: {
                    /* webhook工具 */
                    webhook: [],
                },
                /* 事件消息 */
                eventMessages: [

                ],
                /* 扩展数据， 查询服务端的数据 */
                extra: {
                    /* 模型列表 */
                    models: [],
                    /* 外部工具列表 */
                    tools: {
                        /* 格式化为 Transfer 穿梭框 数据类型 */
                        webhook: [

                        ],
                    },
                    /* 模型参数配置 */
                    modelConfig: {
                        /* 温度 */
                        temperature: {
                            enable: false,
                            value: 0.7
                        },
                        /* top_p */
                        topP: {
                            enable: false,
                            value: 0.8
                        },
                        /* 存在惩罚 */
                        presencePenalty: {
                            enable: false,
                            value: 1
                        },
                        /* 频率惩罚 */
                        frequencyPenalty: {
                            enable: false,
                            value: 1
                        },
                        /* 本次请求返回的最大 Token 数 */
                        maxTokens: {
                            enable: false,
                            value: 1024
                        },
                        /* 是否启用思考模式 */
                        enableThinking: {
                            enable: false,
                            value: false
                        },
                        /* 思考过程的最大长度 */
                        thinkingBudget: {
                            enable: false,
                            value: 1024
                        }
                    }
                },
                /* 页面数据操作 */
                operate: {
                    /* 工具选择 */
                    tools: {
                        /* 选择webhook */
                        webhook: []
                    }
                },
                /* 弹窗 */
                dialog: {
                    /* 选择工具 */
                    tools: {
                        title: "",
                        visible: false,
                        /* 选择工具类型 */
                        type: "",
                    }
                },
                /* 弹窗 */
                drawer: {
                    /* 模型参数配置 */
                    modelConfig: {
                        visible: false
                    }
                }
            }
        },
        computed: {
            username() {
                return setter.userInfo.username;
            },
            agentChatURL() {
                return setter.agentChatURL;
            },
        },
        methods: {
            /* 查询模型列表 类型为 LLM */
            findModels() {
                tools.get("/model/findAll", {type: "LLM"}).then(response => {
                    this.extra.models = response.dataList;
                });
            },

            /* 工具选择自定义label渲染 */
            transferToolRenderContent(h, option) {
                return h("span", {
                    domProps: {
                        innerHTML: option.label
                    }
                });
            },

            /* 查询webhook工具 */
            async findWebHookTools() {
                await tools.get("/tool/webhook/findAllOfBrief").then(response => {
                    response.dataList.forEach(tool => {
                        this.extra.tools.webhook.push(
                            {
                                key: tool.id,
                                label: "<span class='el-tag el-tag--success el-tag--dark el-tag--mini'>" + tool.groupName + "</span>" + " " + tool.toolName,
                                tool: tool
                            }
                        );
                    })
                });
            },

            /* 查询agent详细信息 */
            async findAgentInfo() {
                await tools.get("/agent/info",{agentId: this.agentId}).then(response => {
                    buildAgentInfoData(this, response.data);
                });

                await tools.get("/agent/findEventMessages",{agentId: this.agentId}).then(response => {
                    this.eventMessages = response.dataList;
                });
            },

            /* 选择webhool按钮点击事件 */
            selectWebHookToolsEvent() {
                this.dialog.tools.title = "选择WebHook工具";
                this.dialog.tools.visible = true;
                this.dialog.tools.type = "webhook";
            },

            /* 删除选中的webhook工具 */
            deleteWebHookEvent(webhook) {
                for (let i = 0; i < this.operate.tools.webhook.length; i++) {
                    if (this.operate.tools.webhook[i] == webhook.id) {
                        this.operate.tools.webhook.splice(i, 1);
                        return;
                    }
                }
            },

            /* 发布更新 */
            publishUpdate() {
                if (checkPublishUpdate(this)) {
                    let request = buildPublishUpdateData(this);
                    const loading = tools.loading("发布更新中. . .");
                    tools.post("/agent/publish", request).then(response => {
                        this.$message({
                            type: "success",
                            message: "发布更新成功"
                        });
                        this.eventMessages = [];
                    }).finally(() => {
                        loading.close();
                    });
                }
            },
        },
        watch: {
            "operate.tools.webhook": {
                handler(newVal, oldVal) {
                    let tools = [];
                    newVal.forEach(id => {
                        this.extra.tools.webhook.forEach(obj => {
                            if (id == obj.key) {
                                tools.push(obj.tool);
                            }
                        })
                    });
                    this.tools.webhook = tools;
                }
            }
        },
        async mounted() {
            let loading = tools.loading();

            this.agentId = this.$route.query.agentId;
            this.findModels();
            await this.findWebHookTools();
            await this.findAgentInfo();

            loading.close();
        }
    }

    /* 构建agent info信息 */
    function buildAgentInfoData(that, agentInfo) {
        that.model = agentInfo.modelId;
        that.prompt = agentInfo.prompt;
        that.agentName = agentInfo.name;

        for (let key in agentInfo.llmModelParameter) {
            if (tools.isNotEmpty(agentInfo.llmModelParameter[key])) {
                that.extra.modelConfig[key].enable = true;
                that.extra.modelConfig[key].value = agentInfo.llmModelParameter[key];
            }
        }

        that.operate.tools.webhook = agentInfo.webhookIds;
    }

    /* 发布更新前，检查数据 */
    function checkPublishUpdate(that) {
        if (tools.isEmpty(that.model)) {
            that.$message({
                type: "error",
                message: "模型不能为空"
            });
            return false;
        }
        if (tools.isEmpty(that.prompt)) {
            that.$message({
                type: "error",
                message: "提示词不能为空"
            });
            return false;
        }
        return true;
    }

    /* 构建发布更新的数据 */
    function buildPublishUpdateData(that) {
        let data = {
            agentId: that.agentId,
            modelId: that.model,
            prompt: that.prompt,
            llmModelParameter: buildModelParameter(that),
            webhookIds: that.tools.webhook.map(item => item.id)
        }
        return data;
    }

    /* 构建模型参数 */
    function buildModelParameter(that) {
        let llmModelParameter = {};
        let modelConfig = that.extra.modelConfig;
        for (let key in modelConfig) {
            if (modelConfig[key].enable) {
                llmModelParameter[key] = modelConfig[key].value;
            }
        }
        return llmModelParameter;
    }

</script>

<style type="text/scss">
    .update-prompt {
        height: 30px;
        width: 260px;
    }

    .main-layout {
        display: flex;
        gap: 6px;
        .main-container {
            width: 50%;
        }
    }

    .agent-config {
        overflow: auto;
        .card {
            margin-top: 8px;
        }
    }

    .card {
        display: flex;
        flex-direction: column;
        padding: 8px;
        gap: 8px;
        box-sizing: border-box;
        border: 1px solid #409EFF;
        border-radius: 10px;
        background: #f5f5f8;

        .card-header {
            display: flex;
            height: 26px;
            align-items: center;
            gap: 16px;
            box-sizing: border-box;
            font-weight: bold;
        }

        .card-body {
            flex: 1;
            /*background: white;*/

            textarea {
                height: 100%;
                resize: none;
                border: 0px solid #DCDFE6;
                color: black;
            }

            .el-textarea__inner {
                padding: 2px 8px;
            }
        }

        .card-footer {
            display: flex;
            margin-top: auto;
            height: 26px;
            align-items: center;
            font-weight: bold;
        }
    }

    .tool-card {
        box-sizing: border-box;
        padding: 6px;

        .tool {
            display: flex;
            align-items: center;
            box-sizing: border-box;
            border-radius: 4px;
            padding: 4px;
            gap: 8px;
            /*background: rgba(64, 195, 255, 0.30);*/
            background: white;
        }

        .tool-name {
            font-size: 14px;
            font-weight: 500;
            line-height: 16px;
            flex: 1;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }

        .tool-operate {
            margin-left: auto;
            display: flex;
            gap: 8px;
            padding-right: 6px;

            .el-icon-question:hover {
                cursor: pointer;
                color: rgba(64,158,255) !important;
            }

            .el-icon-delete:hover {
                cursor: pointer;
                color: rgba(245,108,108) !important;
            }
        }
    }

    .el-slider__input {
        width: 100px !important;
    }
    .el-form-item__content {
        display: flex;
        align-items: center;
        height: 40px;
    }
    .el-slider {
        flex: 1;
        margin-left: 20px
    }
    .el-transfer-panel {
        width: 280px !important;
    }

</style>
